package com.study.fiyweight;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 享元模式
 * 运用共享技术有效的支持大量细粒度的对象
 *
 * 举个例子: 游戏地图中可能有很多的场景 比如树 这些树其实本质上就那几种 只是可能随机生成在地图上的坐标上 那么生成这么多树我每个树都去new一个吗 不可能的 会给内存跟cpu很大压力
 * 这时候这种设计模式就有很大的用处了
 *
 * 像很多时候jdk给我们提供了很多指令 比如我们用BigDecimal的时候 BigDecimal bi = BigDecimal.zero() 这种就是因为底层帮我们封装好了可以避免我们疯狂创建对象,我们直接用就好了
 *
 * 其实这种也可以用枚举来做 Tree的种类每一种是一个单例
 *
 */
public class FlyWeightTest {

    public static void main(String[] args) {

        //很明显这2个treeNode里面的Tree都是同个对象
        TreeNode treeNode1 = new TreeNode(3,4,TreeFactory.getTree("name1","data1"));
        TreeNode treeNode2 = new TreeNode(3,4,TreeFactory.getTree("name1","data1"));


    }

}

//按照上面说的树 来试着写一个看看
class TreeFactory{
    private static Map<String,Tree> map = new ConcurrentHashMap<>();

    public static Tree getTree(String name ,String data){

        if(map.containsKey(name)){
            return map.get(name);
        }

        Tree tree = new Tree(name,data);
        map.put(name,tree);
        return tree;

    }


}


//带 x y 坐标
class TreeNode{
    private int x;
    private int y;
    private Tree tree;

    public TreeNode(int x, int y, Tree tree) {
        this.x = x;
        this.y = y;
        this.tree = tree;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public Tree getTree() {
        return tree;
    }

    public void setTree(Tree tree) {
        this.tree = tree;
    }
}


class Tree{
    //final修饰的变量 初始化设置完成后就再也不能修改了
    private final String name;
    private final String date;

    public Tree(String name, String date) {
        System.out.println( " Tree " + name + " created ");
        this.name = name;
        this.date = date;
    }

    //我们把set方法全部干掉

    public String getName() {
        return name;
    }

    public String getDate() {
        return date;
    }

}
